Minor&Major&Full GC

Minor GC

新生代通常存活时间比较短,是基于复制算法进行回收的。从年轻代空间(包括Eden两个Survivor区域)回收内存被称为Minor GC

当JVM无法为一个新的对象分配空间时会触发Minor GC,比如当Eden区满了。所以分配率越高,越频繁执行Minor GC

内存池被填满的时候,其中的内容全部会被复制,指针会从0开始跟踪空闲内存。Eden 和 Survivor 区进行了标记和复制操作,取代了经典的标记、扫描、压缩、清理操作。所以 Eden 和 Survivor 区不存在内存碎片。写指针总是停留在所使用内存池的顶部。

执行Minor GC操作时,不会影响到永久代。从永久代到年轻代的引用被当成GC Roots,从年轻代永久代的引用在标记阶段被直接忽略掉。

所有的Minor GC都会触发Stop-The-World,这个过程非常短暂。大部分Eden区中的对象都能被认为是垃圾,永远也不会被复制到Survivor区或者老年代空间。如果正好相反,Eden区大部分新生对象不符合GC条件,Minor GC执行时暂停的时间将会长很多。

Major GC & Full GC

老年代与新生代不同,老年代对象存活的时间比较长、比较稳定,因此一般采用标记整理算法来进行回收,当然这也跟垃圾收集器相关。

Major GC是清理老年代Full GC是清理整个堆空间包括年轻代老年代。出现Major GC经常会伴随至少一次的Minor GC,且Major GC的速度一般会比Minor GC慢10倍以上。

许多Major GC是由Minor GC触发的,所以很多情况下将这两种GC分离是不太可能的。另一方面,许多现代垃圾收集机制会清理部分永久代空间

Full GC触发条件:

  • 调用System.gc()时,系统建议执行Full GC,但是不必然执行。
  • 老年代空间不足。
  • 方法去空间不足。
  • 通过Minor GC后进入老年代的平均大小大于老年代的可用内存。
  • 由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小。